package com.woniu.userassembly.controller;

import com.alibaba.fastjson.JSONException;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.rabbitmq.client.Channel;


import com.woniu.feignClient.UserFeignClient;
import com.woniu.*;

import com.woniu.feignclients.IdentifyClient;
import com.woniu.ly.model.common.Result;
import com.woniu.ly.model.model.*;
import com.woniu.userassembly.component.UserSeckillComponent;
import com.woniu.userassembly.identifycontroller.util.OssUtil;
import com.woniu.userassembly.model.AlipayConfig;
import com.woniu.userassembly.model.Fenye;
import com.woniu.userassembly.model.HttpUtils;
import com.woniu.userassembly.model.info.UserSeckillInfo;
import com.woniu.userassembly.service.TCardService;
import com.woniu.userassembly.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@Slf4j
@CrossOrigin("*")
public class UserController implements UserFeignClient {
    @Autowired
    private UserService userService;
    @Autowired
    private TCardService tCardService;
    static List<Integer> travelerOrderId = new ArrayList<>();

    //唯一登录接口(用户名,密码)
    @Override
    public Result login(String userName, String userPassword) {
        User login = userService.login(userName);
        if (login != null) {
            if (login.getUserPassword().equals(userPassword)) {
                if (userService.quanxian(userName).equals("管理员")) {
                    //管理员登录成功
                    return Result.success("欢迎管理员");
                } else {
                    //用户登录成功
                    return Result.success(login);
                }

            } else {
                return Result.fail("密码输入错误,请重新输入！");
            }
        } else {
            return Result.fail("用户名不存在！");
        }

    }
    private static int Rand;
    private static String userN;
    private static String userP;
    private static String userT;
    private static boolean aBoolean=true;
    //用户注册接口(用户名,密码,电话)
    @Override
    public Result register(String userName, String userPassword, String userTel) {

        User login = userService.login(userName);
        if (login != null) {
            return Result.fail("此用户名已存在,请更换用户名！");
        } else {
            //用户名必须为4-8位任意字符或数字
            if (userName.matches("[A-Za-z0-9]{4,8}")) {
                //密码必须为6-10位任意字符或数字
                if (userPassword.matches("[A-Za-z0-9]{6,10}")) {
                    //手机号格式必须为11位正常手机号
                    if (userTel.matches("[1][3,4,5,6,7,8,9][0-9]{9}")) {

                        Random random = new Random();
                        String host = "http://www.api51.cn";
                        String path = "/api/smsApi/send";
                        String method = "POST";
                        Map<String, String> headers = new HashMap<String, String>();
                        int rand = random.nextInt(9000) + 1000;

                        //根据API的要求，定义相对应的Content-Type
                        headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
                        Map<String, String> querys = new HashMap<String, String>();
                        Map<String, String> bodys = new HashMap<String, String>();
                        bodys.put("mobile", userTel);
                        bodys.put("params", rand + "");
                        bodys.put("sign", "API无忧");
                        bodys.put("token", "fa56a997ef3d0193aa66be9997ac44d4");
                        bodys.put("tpl_id", "46792");

                        try {
                            /**
                             * 重要提示如下:
                             * HttpUtils请从
                             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
                             * 下载
                             *
                             * 相应的依赖请参照
                             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
                             */
                            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
                            log.info("response结果:{}", response);
                            //获取response的body
                            //System.out.println(EntityUtils.toString(response.getEntity()));
                            Rand=rand;
                            userN=userName;
                            userP=userPassword;
                            userT=userTel;
                            aBoolean=false;
                           return Result.success("验证码已发送,请输入验证码");

                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    } else {
                        return Result.fail("手机电话格式错误！请重新输入");
                    }
                } else {
                    return Result.fail("密码应为6-10位任意字符,请重新输入");
                }
            } else {
                return Result.fail("用户名应为4-8位任意字符,请重新输入");
            }

            return Result.success("恭喜！注册成功");
        }

    }
    //验证码
    @Override
    public Result code(int code) {
        if(aBoolean==false){
            if(code==Rand){
                userService.register(userN,userP,userT);
                aBoolean=true;
                return Result.success("恭喜你,注册成功!");
            }else {
                return Result.fail("验证码输入错误！");
            }
        }else {
            return Result.fail("无效验证码,请先注册");
        }

    }

    //查询产品(关键字)
    @Override
    public Result selectProduct(String keyWord) {
        List<Product> list = userService.selectProduct(keyWord);
        return Result.success(list);
    }

    //查看订单(分页查询)
    //userOrder模型里少一个userOrderStatus字段
    @Override
    public Result selectOrder(int pageIndex, int pageNum,HttpServletRequest httpServletRequest) {
        List<com.woniu.userassembly.model.UserOrder> userOrders = userService.selectOrder((pageIndex - 1) * pageNum, pageNum,Integer.parseInt(httpServletRequest.getHeader("userId")));
        int count = userService.orderCount(Integer.parseInt(httpServletRequest.getHeader("userId")));
        int pageCount = count % pageNum == 0 ? count / pageNum : count / pageNum + 1;
        Fenye fenye = new Fenye();
        fenye.setCount(count);
        fenye.setList(userOrders);
        fenye.setPageCount(pageCount);
        fenye.setPageIndex(pageIndex);
        return Result.success(fenye);
    }

    //用户下单
    @Override
    public Result makeOrder(HttpServletRequest httpServletRequest, int tourId) {
        com.woniu.userassembly.model.UserOrder userOrder = new com.woniu.userassembly.model.UserOrder();
        userOrder.setTourId(tourId);
        userOrder.setUserId(Integer.parseInt(httpServletRequest.getHeader("userId")));
        Tour tour = userService.selectTourById(tourId);
        userOrder.setUserOrderPrice(travelerOrderId.size()*tour.getTourPrice());
        userOrder.setUserOrderStatus("下单");
        userOrder.setTourGenre("普通团");
        userOrder.setUserOrderTime(Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
        userService.makeOrder(userOrder);//用户订单
        for (int traId : travelerOrderId) {
            UserOrderDetail userOrderDetail = new UserOrderDetail();
            userOrderDetail.setTravelerId(traId);
            userOrderDetail.setUserOrderDetailPrice(userOrder.getUserOrderPrice() / travelerOrderId.size());
            userOrderDetail.setUserOrderId(userOrder.getUserOrderId());
            userOrderDetail.setUserOrderDetailStatus("正常");
            userService.makeOrderDetail(userOrderDetail);//用户详情订单
        }
        return Result.success("下单成功！");
    }

    //添加出行人

    @Override
    public Result addTraveler( String travelerTel,  HttpServletRequest httpServletRequest,MultipartFile card,MultipartFile card1) throws JSONException {
       List<String> list=userService.selectTel();
       travelerOrderId.clear();
       int upCardId=0;
       //用户添加自己(更新)
        Card idCard1=null;
        Result result1=null;
        if(list.contains(travelerTel)){
            try {
               idCard1=identifyController.identifyFront(card);
              result1 = identifyController.identifyBack(card1);
                Timestamp data = (Timestamp) result1.getData();
                Card card2=userService.selectCard(idCard1.getCardNum());

                if(null!=card2){
                    if(data.getTime()>=card2.getCardIndate().getTime()){
                        card2.setCardIndate(idCard1.getCardIndate());
                        upCardId=userService.updateCard(card2);
                        userService.update(upCardId,Integer.parseInt(httpServletRequest.getHeader("userId")));
                        Traveler traveler=new Traveler();
                        traveler.setCardId(card2.getCardId());
                        traveler.setUserId(Integer.parseInt(httpServletRequest.getHeader("userId")));
                        traveler.setTravelerTel(travelerTel);
                        traveler.setTravelerType("直客");
                        userService.addTraveler(traveler);
                        travelerOrderId.add(traveler.getTravelerId());
                        return Result.success("更新了身份证！添加出行人成功");
                    }

                }
            } catch (org.json.JSONException | ParseException e) {
                e.printStackTrace();
            }
           //用户添加自己(添加)
            identifyController  identifyController=new identifyController();
            userService.addCard(idCard1);
            Timestamp data =(Timestamp) result1.getData();
            tCardService.addcardtime(data,idCard1.getCardId());
            userService.insertCardId(idCard1.getCardId(),travelerTel);


            Traveler traveler = new Traveler();

            traveler.setTravelerTel(travelerTel);
            traveler.setTravelerType("直客");
            traveler.setUserId(Integer.parseInt(httpServletRequest.getHeader("userId")));
            traveler.setCardId(idCard1.getCardId());
            userService.addTraveler(traveler);
            travelerOrderId.add(traveler.getTravelerId());
            return Result.success("添加成功");
       }else{//用户添加其他人
            Card idCard = null;
            Result result=null;
            try {
                 idCard = identifyController.identifyFront(card);
                Card card2=userService.selectCard(idCard.getCardNum());
                 result = identifyController.identifyBack(card1);
                Timestamp data = (Timestamp) result.getData();
                if(null!=card2){
                    if(data.getTime()>=card2.getCardIndate().getTime()){
                        card2.setCardIndate(idCard.getCardIndate());
                        upCardId=userService.updateCard(card2);
                        Traveler traveler=new Traveler();
                        traveler.setCardId(card2.getCardId());
                        traveler.setUserId(Integer.parseInt(httpServletRequest.getHeader("userId")));
                        traveler.setTravelerTel(travelerTel);
                        traveler.setTravelerType("直客");
                        userService.addTraveler(traveler);
                        travelerOrderId.add(traveler.getTravelerId());
                        return Result.success("更新了身份证！添加出行人成功");
                    }

                }
            } catch (org.json.JSONException | ParseException e) {
                e.printStackTrace();
            }
            Traveler traveler = new Traveler();

            traveler.setTravelerTel(travelerTel);
            traveler.setTravelerType("直客");
            traveler.setUserId(Integer.parseInt(httpServletRequest.getHeader("userId")));


            //识别证明
            identifyController  identifyController=new identifyController();

            userService.addCard(idCard);
            traveler.setCardId(idCard.getCardId());
            userService.addTraveler(traveler);
            travelerOrderId.add(traveler.getTravelerId());

            Timestamp data =(Timestamp) result.getData();
            tCardService.addcardtime(data,idCard.getCardId());
            return Result.success("添加成功");
        }




    }

    //用户投诉
    @Override
    public Result makeComplaints(int orderId, String complaintsContent, HttpServletRequest httpServletRequest) {
        Complaints complaints = new Complaints();
        complaints.setComplaintsContent(complaintsContent);
        complaints.setComplaintsTime(Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
        complaints.setOrderId(orderId);
        complaints.setUserId(Integer.parseInt(httpServletRequest.getHeader("userId")));
        userService.makeComplaints(complaints);
        return Result.success(complaints.getComplaintsId());
    }

    //用户评论(评论加图片)
    @Override
    public Result makeComment(int productId, String commentContent, HttpServletRequest httpServletRequest, List<MultipartFile> list) {
        Comment comment = new Comment();
        OssUtil ossUtil=new OssUtil();
        comment.setCommentContent(commentContent);
        comment.setCommentTime(Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
        comment.setProductId(productId);
        String userId = httpServletRequest.getHeader("userId");
        comment.setUserId(Integer.parseInt(userId));
        userService.makeComment(comment);
        for (MultipartFile multipartFile : list) {
            String substring = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf("."));
            String fileName = UUID.randomUUID() + substring;
            try {
                multipartFile.transferTo(new File("D:\\tmp\\" + fileName));
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                ossUtil.upFiles(fileName,"D:\\tmp\\" + fileName);
            } catch (IOException e) {
                e.printStackTrace();
            }
            CommentImg commentImg = new CommentImg();
            commentImg.setCommentId(comment.getCommentId());
            commentImg.setCommentImgUrl("https://images-traveler.oss-cn-chengdu.aliyuncs.com/" + fileName);
            userService.commentImg(commentImg);
        }
        return Result.success("评论成功！");
    }


    //取消订单
    @Override
    public Result cancelOrder(cancelOrderInfo cancelOrderInfo,HttpServletRequest httpServletRequest) {
        UserOrder userOrder = userService.selectOrderById(cancelOrderInfo.getOrderId());
        if(userOrder==null){
            return Result.fail("没有此订单，请确认！");
        }
        if(userOrder.getUserOrderStatus().equals("下单")||userOrder.getUserOrderStatus().equals("待支付")){
            userService.cancelOrder(cancelOrderInfo.getOrderId());//取消用户订单
            userService.cancelOrderDetail(cancelOrderInfo.getOrderId());//取消用户订单详情
        }else if(userOrder.getUserOrderStatus().equals("已付款")){
           //调用退款接口
            System.out.println(cancelOrderInfo.getTravelerId());
            System.out.println(cancelOrderInfo.getOrderId());
           return refund(cancelOrderInfo.getOrderId(),httpServletRequest,cancelOrderInfo.getTravelerId());
        }else{
            return Result.fail("请确认订单状态");
        }

        return Result.success("取消订单成功");
    }


    private static int OrderId;
    private static int UserId;
    private static double Price;
    private static String name;
    //用户付款
//支付宝API(schyuh1541@sandbox.com)
    public void pay(int orderId, HttpServletResponse rep) {
        if (orderId != 0) {
            double price = userService.selectOrderPrice(orderId);
            int userId=userService.selectOrderUserId(orderId);
            OrderId=orderId;
            UserId=userId;
            Price=price;
            AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
            AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
            alipayRequest.setReturnUrl(AlipayConfig.return_url);
            alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

            //商户订单号，商户网站订单系统中唯一订单号，必填
            String out_trade_no = orderId+"";
            //付款金额，必填   如果你的类型是double需写成  price+"" 的形式，否则当含有小数部分时金额错误
            String total_amount = price + "";
            //订单名称，必填
            String subject = "旅游费用";
            //商品描述，可空
            String body = "商品名";

            // 该笔订单允许的最晚付款时间，逾期将关闭交易。取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
            String timeout_express = "1h";

            String qr_code_timeout_express = "2m";

            alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                    + "\"total_amount\":\"" + total_amount + "\","
                    + "\"subject\":\"" + subject + "\","
                    + "\"body\":\"" + body + "\","
                    + "\"timeout_express\":\"" + timeout_express + "\","
                    + "\"qr_code_timeout_express\":\"" + qr_code_timeout_express + "\","
                    + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
            try {
                String form = alipayClient.pageExecute(alipayRequest).getBody();
                rep.setContentType("text/html;charset=" + AlipayConfig.charset);
                rep.getWriter().write(form);//直接将完整的表单html输出到页面
                rep.getWriter().flush();
            } catch (AlipayApiException | IOException e) {
                e.printStackTrace();
            }
        } else {
            rep.setContentType("text/html;charset=" + AlipayConfig.charset);
            try {
                rep.getWriter().write("订单id不存在,请重输入");//直接将完整的表单html输出到页面
                rep.getWriter().flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //用户退款
    @Override
    public Result refund(int orderId,HttpServletRequest httpServletRequest,List<Integer> travelerId) {
        System.out.println(travelerId);
        int num = userService.travelNum(orderId);
        boolean contains=true;
        PlatfromStatement platfromStatement=new PlatfromStatement();
        List<Integer> integers = userService.selectOrderIdd();
        if (integers.contains(orderId)) {
            List<Integer> travelId=userService.selectTravelerIdByUserId(Integer.parseInt(httpServletRequest.getHeader("userId")));
            for(int id:travelerId){
                 contains = travelId.contains(id);
            }
            if(contains){
                double price = userService.selectOrderPrice(orderId);
                userService.refundOrder(orderId);

                platfromStatement.setOrderId(orderId);
                platfromStatement.setOrderType("用户");
                platfromStatement.setStatementAmount(price/num*travelerId.size());
                platfromStatement.setStatementType("用户退款");
                platfromStatement.setStatementTime(Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
                userService.platformStatement(platfromStatement);
                double v = userService.selectLastPlatformAccount();
                for(int traId:travelerId){
                    userService.refundTraveler(traId);
                    userService.platformAccount(v-(price/num),platfromStatement.getStatementId());
                }
                //用户账户表
                com.woniu.userassembly.model.UserAccount userAccount =new com.woniu.userassembly.model.UserAccount();
                userAccount.setUserAccountContent("用户自行退款");
                userAccount.setUserAccountMoney(price/num*travelerId.size());
                userAccount.setUserAccountTime(Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
                userAccount.setUserAccountType("退款");
                userAccount.setUserId(Integer.parseInt(httpServletRequest.getHeader("userId")));
                userService.refundOrderPrice(userAccount);

                return Result.success("退款成功" + price/num*travelerId.size());
            }else {
                return Result.fail("不存在的出行人,请确认!");
            }

        } else {
            return Result.fail("不存在的订单！请重新确认订单");
        }

    }

//同步支付回调
    @Override
    public Result success(HttpServletRequest httpServletRequest) {
        System.out.println(httpServletRequest.getHeader("userId"));
        return Result.success("支付成功！");
    }
//查看出行人(分页)
    @Override
    public Result selectTraveler(HttpServletRequest httpServletRequest,int pageIndex,int pageNum) {
        String userId = httpServletRequest.getHeader("userId");
        List<Traveler> list=userService.selectTraveler(Integer.parseInt(userId),(pageIndex-1)*pageNum,pageNum);
        int count=userService.travelerCount(Integer.parseInt(userId));
        int pageCount=count%pageNum==0?count/pageNum:count/pageNum+1;
        Fenye fenye=new Fenye();
        fenye.setPageIndex(pageIndex);
        fenye.setPageCount(pageCount);
        fenye.setList(list);
        fenye.setCount(count);
        return Result.success(fenye);
    }
//根据时间查询旅行团
    @Override
    public Result selectTourByTime(String timestamp) {

        List<Tour> tours=userService.selectTourByTime(timestamp);
        if(tours.size()==0){
            return  Result.success("没有该时间的旅游团！");
        }
        return Result.success(tours);
    }


    //身份证过期推送
    @RabbitListener(queues = "card.time.queue")
    public void sendCardTime(List<String> message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG)long log1) throws IOException {
         log.info("接收到了消息{}",message);
         for(String s:message){
            System.out.println("尊敬的用户："+s+",您的证件已经过期,为避免意外情况,请及时更新您的身份证！");
        }
        channel.basicAck(log1,false);
    }
    // 出行人退款
    @RabbitListener(queues ="refund.money.queue")
    public void refundMoney(List<Traveler> travelers, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG)long log1) throws IOException {
        log.info("接收到了消息{}",travelers);
        for(Traveler traveler:travelers){
            // 根据出行人信息（电话等），发送通知
            System.out.println("出行人信息："+traveler);
        }
        channel.basicAck(log1,false);
    }

    @Autowired
    private UserSeckillComponent seckillComponent;

    @Autowired
    private RedisTemplate redisTemplate;
//
//    private int seckillOrderId = 100;

    //抢购秒杀团名额
    @GetMapping("joinSeckillTour")
    public void joinSeckillTour(int userId,double price,int travelNum,int seckillTourId,HttpServletResponse httpServletResponse){
        String message = seckillComponent.joinSeckillTour(userId, travelNum, seckillTourId);
        if(message.equals("抢购成功")){
              com.woniu.userassembly.model.UserOrder userOrder=new com.woniu.userassembly.model.UserOrder();
              userOrder.setTourGenre("秒杀团");
              userOrder.setUserOrderTime(Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
              userOrder.setUserOrderPrice(price);
              userOrder.setUserId(userId);
              userOrder.setUserOrderStatus("待支付");
              userOrder.setTourId(seckillTourId);
              int orderId = userService.makeOrder(userOrder);
              OrderId=orderId;
              //调支付接口
              pay(orderId,httpServletResponse);
        }
    }



}